/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package lib.model;

import lib.exceptions.InvalidLengthException;
import lib.exceptions.InvalidPeriodFrequencyException;
import lib.exceptions.InvalidPeriodicDate;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

/**
 *
 * @author jorge
 */
public class PeriodicInterval {

    private Interval interval;
    private Interval validDates;
    private Period period;

    public PeriodicInterval(Interval interval,
            Interval validDates,
            Period period)
            throws InvalidPeriodFrequencyException,
            InvalidPeriodicDate {
        this.interval = interval;
        this.validDates = validDates;
        this.period = period;
        if (interval.Length() > validDates.Length()) {
            throw new InvalidPeriodFrequencyException();
        }
        if (!validDates.contains(interval)) {
            throw new InvalidPeriodicDate();
        }
    }

    public List<Interval> getAllIntervals() {
        List<Interval> result = new ArrayList<Interval>();
        Interval tmpInterval = null;
        Calendar tmpStart = null;

        if (period == Period.NONE) {
            result = new ArrayList<Interval>();
            result.add(interval);
            return result;
        }

        int field;

        result.add(interval);
        switch (period) {
            case DAILY:
                field = Calendar.DATE;
                break;
            case WEEKLY:
                field = Calendar.WEEK_OF_YEAR;
                break;
            case MONTHLY:
                field = Calendar.MONTH;
                break;
            case YEARLY:
                field = Calendar.YEAR;
                break;
            default:
                field = -1;
                break;
        }
        tmpStart = (Calendar) interval.getStart().clone();
        tmpStart.add(field, -1);
        try {
            tmpInterval = new Interval(tmpStart, interval.Length());
        } catch (InvalidLengthException ile) {
        }
        while (validDates.contains(tmpInterval)) {
            result.add(0, tmpInterval);
            tmpStart = (Calendar) tmpInterval.getStart().clone();
            tmpStart.add(field, -1);
            try {
                tmpInterval = new Interval(tmpStart, interval.Length());
            } catch (InvalidLengthException ile) {
            }
        }
        tmpStart = (Calendar) interval.getStart().clone();
        tmpStart.add(field, 1);
        try {
            tmpInterval = new Interval(tmpStart, interval.Length());
        } catch (InvalidLengthException ile) {
        }
        while (validDates.contains(tmpInterval)) {
            result.add(tmpInterval);
            tmpStart = (Calendar) tmpInterval.getStart().clone();
            tmpStart.add(field, 1);
            try {
                tmpInterval = new Interval(tmpStart, interval.Length());
            } catch (InvalidLengthException ile) {
            }
        }
        return result;
    }

    public Interval getInterval() {
        return interval;
    }

    public Period getPeriod() {
        return period;
    }

    public Interval getValidDates() {
        return validDates;
    }
}
